
/**
 * 绘制特效点
 * @param {Earth} options.earth 渲染容器
 * @param {Array} options.position 坐标位置 [ lng, lat, h ]
 * @param {Array} options.color 特效点颜色 colorArray
 * @param {Array} options.scale 特效点缩放等级 [长, 宽, 高]
 * 
 * @returns {Array<CustomPrimitive>} CustomPrimitive实例列表组 由4个CustomPrimitive组成
 */
function DrawBasePoint(options) {
    let earth = options.earth
    let position = [ options.position[0] * Math.PI / 180, options.position[1] * Math.PI / 180, options.position[2] || 1.5]
    let color = options.color || [0.5, 0.8, 1, 2]
    let scale = options.scale || [5000, 5000, 100]
    let drawType = options.drawType || [ true, true, true, true ]

    let pList = []

    // 底面
    if (drawType[0]) {
        const evalString = `
            p.canvasWidth = 512;
            p.canvasHeight = 512;
            p.drawCanvas(ctx => {
                var gradient = ctx.createRadialGradient(256, 256, 0, 256, 256, 256);
                gradient.addColorStop(0.1, "rgba(255, 255, 255, 1.0)");
                gradient.addColorStop(0.2, "rgba(255, 255, 255, 0.0)");
                gradient.addColorStop(0.4, "rgba(255, 255, 255, 0.9)");
                gradient.addColorStop(0.6, "rgba(255, 255, 255, 0.0)");
                gradient.addColorStop(0.9, "rgba(255, 255, 255, 0.5)");
                gradient.addColorStop(1.0, "rgba(255, 255, 255, 1.0)");

                ctx.clearRect(0, 0, 512, 512);
                ctx.beginPath();
                ctx.arc(256, 256, 256, 0, Math.PI * 2, true);
                // ctx.fillStyle = "rgb(0, 155, 255)";
                ctx.fillStyle = gradient;
                ctx.fill();
                ctx.restore();
            });
        `;

        const config = {
            evalString,
            position: [...position],
            scale: [...scale],
            positions: [...XE.Obj.CustomPrimitive.Geometry.unitSquare.positions],
            sts: [...XE.Obj.CustomPrimitive.Geometry.unitSquare.sts],
            indices: [...XE.Obj.CustomPrimitive.Geometry.unitSquare.indices],
            renderState: XE.Obj.CustomPrimitive.getRenderState(true, true),
            color: [...color],
            canvasWidth: 512,
            canvasHeight: 512,
        };

        let p = new XE.Obj.CustomPrimitive(earth);
        p.xbsjFromJSON(config);
        pList.push(p)
    }

    // 底面动态辐射波
    if (drawType[1]) {
        const evalString = `
            p.canvasWidth = 512;
            p.canvasHeight = 512;
            p.drawCanvas(ctx => {
                ctx.clearRect(0, 0, 512, 512);

                ctx.strokeStyle = "rgb(255, 255, 255)";
                ctx.setLineDash([80, 80]);
                ctx.lineWidth = 30;
                ctx.arc(256, 256, 241, 0, Math.PI * 2, true);
                ctx.stroke();
            });
        `;

        const preUpdateEvalString = `
            if (typeof p.dAngle === 'undefined') p.dAngle = 0.0;
            if (typeof p.dt === 'undefined') p.dt = 0.01;

            p.dAngle += 10.0;
            if (p.dAngle > 360.0) {
                p.dAngle = 0.0;
            }
            p.rotation[0] = p.dAngle / 180.0 * Math.PI;

            p.dt += 0.02;
            if (p.dt > 1.0) p.dt = 0.01;

            p.scale[0] = ${ scale[0] } * p.dt;
            p.scale[1] = ${ scale[1] } * p.dt;
        `;

        const config = {
            evalString,
            preUpdateEvalString,
            position: [...position],
            scale: scale,
            positions: [...XE.Obj.CustomPrimitive.Geometry.unitSquare.positions],
            sts: [...XE.Obj.CustomPrimitive.Geometry.unitSquare.sts],
            indices: [...XE.Obj.CustomPrimitive.Geometry.unitSquare.indices],
            renderState: XE.Obj.CustomPrimitive.getRenderState(true, true),
            color: [...color],
            canvasWidth: 512,
            canvasHeight: 512,
        };

        let p = new XE.Obj.CustomPrimitive(earth);
        p.xbsjFromJSON(config);
        pList.push(p)
    }

    // 柱体
    if (drawType[2]) {
        const fragmentShaderSource =
        `
        varying vec3 v_positionEC;
        varying vec3 v_normalEC;
        varying vec2 v_st;
        varying vec4 v_color;
        uniform sampler2D u_image;
        uniform vec4 u_color;
        void main()
        {
            float powerRatio = fract(czm_frameNumber / 30.0) + 1.0;
            float alpha = pow(1.0 - v_st.t, powerRatio);
            gl_FragColor = vec4(u_color.rgb, alpha*u_color.a);
        }
        `;
        const renderState = XE.Obj.CustomPrimitive.getRenderState(true, true);
        renderState.cull.enabled = false;
        const cylinder = XE.Obj.CustomPrimitive.Geometry.createCylinder(0.3, 2.0, 1.0, 6);
        const config = {
            position: [...position],
            scale: [5/50*scale[0], 5/50*scale[1], 300*scale[2]],
            positions: cylinder.positions,
            sts: cylinder.sts,
            indices: cylinder.indices,
            renderState,
            color: [...color],
            canvasWidth: 1.0,
            fragmentShaderSource,
        };

        let p = new XE.Obj.CustomPrimitive(earth);
        p.xbsjFromJSON(config);
        pList.push(p)
    }

    // 柱体粒子
    if (drawType[3]) {
        const fragmentShaderSource =
        `
        varying vec3 v_positionEC;
        varying vec3 v_normalEC;
        varying vec2 v_st;
        varying vec4 v_color;
        uniform sampler2D u_image;
        uniform vec4 u_color;
        void main()
        {
            vec3 positionToEyeEC = -v_positionEC;
            vec3 normalEC = normalize(v_normalEC);
            normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);

            float dt = fract(czm_frameNumber / 90.0);
            vec2 st = fract(vec2(1.0) + v_st - vec2(dt, dt));
            vec4 imageColor = texture2D(u_image, st);

            vec3 diffuse = imageColor.rgb;
            float alpha = imageColor.a;

            diffuse *= v_color.rgb;
            alpha *= v_color.a;

            diffuse *= u_color.rgb;
            alpha *= u_color.a;

            gl_FragColor = vec4(diffuse, alpha * pow(1.0 - v_st.t, 2.0));
        }
        `;

        const evalString = `
            p.canvasWidth = 32;
            p.canvasHeight = 256;
            Cesium.Resource.createIfNeeded('http://47.95.193.52:9090/assets/img/particles.png').fetchImage().then(function(image) {
                if (p.isDestroyed()) {
                    return
                }
                p.drawCanvas(ctx => {
                    ctx.clearRect(0, 0, 32, 256);
                    ctx.drawImage(image, 0, 0);
                });
            });
        `;

        const renderState = XE.Obj.CustomPrimitive.getRenderState(true, true);
        renderState.cull.enabled = false;
        const cylinder = XE.Obj.CustomPrimitive.Geometry.createCylinder(4.0, 4.0, 1.0, 6);
        const config = {
            fragmentShaderSource,
            evalString,
            position: [...position],
            scale: [3/50*scale[0], 3/50*scale[1], 300*scale[2]],
            positions: cylinder.positions,
            sts: cylinder.sts,
            indices: cylinder.indices,
            color: [...color],
            canvasWidth: 32,
            canvasHeight: 256,
            renderState,
        };

        const p = new XE.Obj.CustomPrimitive(earth);
        p.xbsjFromJSON(config);
        pList.push(p)
    }

    this.pList = pList 
}

DrawBasePoint.prototype.setShow = function (options) {

    this.pList.forEach(item => {
        item.show = options
    })

}

DrawBasePoint.prototype.destroy = function () {
    this.pList.forEach(item => {
        item.destroy()
    })
    this.pList = null
}


export default DrawBasePoint